﻿using System;
using System.ComponentModel;
using System.IO;
using System.Text;
using System.Windows.Input;
using Monti.Docking;
using Monti.MVVM;
using WikiUploader.Classes.MediaWikiAccess;
using WikiUploader.Controls;

namespace WikiUploader.Classes
{
   /// <summary>
   /// Data for a wiki editor.
   /// </summary>
   public class WikiEditor : DockItem
   {
      private RelayCommand m_CmdSave;
      private RelayCommand m_CmdLoad;

      private readonly WikiEditorView m_View;

      /// <summary>
      /// Initializes a new wiki browser.
      /// </summary>
      public WikiEditor (MediaWikiPage page)
      {
         this.Page = page;
         this.Title = "Loading...";
         this.m_View = new WikiEditorView { DataContext = this };
         this.Content = this.m_View;
         this.Page.PropertyChanged += this.PagePropertyChanged;
         this.Closing += this.OnClosing;
      }

      #region Properties

      /// <summary>
      /// Gets the current page of the browser.
      /// </summary>
      public MediaWikiPage Page { get; private set; }

      /// <summary>
      /// Gets or Sets the wiki site.
      /// </summary>
      public MediaWikiSite Site
      {
         get { return this.Page.Site; }
      }

      /// <summary>
      /// Gets or Sets if the site is connected or not.
      /// </summary>
      public bool IsConnected
      {
         get { return this.Page != null && this.Page.IsLoaded; }
      }

      #endregion

      #region Commands

      /// <summary>
      /// Gets the command to save the current page.
      /// </summary>
      public ICommand SaveCommand
      {
         get { return this.m_CmdSave ?? (this.m_CmdSave = new RelayCommand (this.Save, this.CanEditPage)); }
      }

      /// <summary>
      /// Gets the command to load the current page.
      /// </summary>
      public ICommand LoadCommand
      {
         get { return this.m_CmdLoad ?? (this.m_CmdLoad = new RelayCommand (this.Load, this.CanEditPage)); }
      }
      
      /// <summary>
      /// Loads the current page.
      /// </summary>
      /// <param name="obj">Command parameter.</param>
      private void Load (object obj)
      {
         this.Page.Refresh ();
      }

      /// <summary>
      /// Saves the current page.
      /// </summary>
      /// <param name="obj">Command parameter.</param>
      private void Save (object obj)
      {
         this.Page.Content = this.m_View._Editor.Text;
         this.Page.Save ();
      }

      /// <summary>
      /// Checks if the save command can execute.
      /// </summary>
      /// <param name="obj">Command parameter.</param>
      /// <returns>True if command can execute, otherwise false.</returns>
      private bool CanEditPage (object obj)
      {
         return this.Page != null;
      }

      #endregion

      #region Methods

      /// <summary>
      /// Occurs when the tab item is closing.
      /// </summary>
      /// <param name="sender">Dock group.</param>
      /// <param name="e">DockContentCancelEventArgs.</param>
      private void OnClosing (object sender, DockContentCancelEventArgs e)
      {
         this.Page.PropertyChanged -= this.PagePropertyChanged;
      }

      /// <summary>
      /// Occurs when a property changes in the page.
      /// </summary>
      /// <param name="sender">Page.</param>
      /// <param name="e">PropertyChangedEventArgs.</param>
      private void PagePropertyChanged (object sender, PropertyChangedEventArgs e)
      {
         if (e.PropertyName == "IsLoaded")
         {
            this.Title = this.Page.Title;
            this.ToolTip = this.Page.IsLoaded ? this.Page.Url : "Page does not exist.";
         }
         else if (e.PropertyName == "Content")
         {
            MainViewModel.SyncContex.Send (delegate
               {
                  this.m_View._Editor.Load (new MemoryStream (Encoding.Default.GetBytes (this.Page.Content)));
               }, null);
         }
      }

      #endregion
   }
}
